package main

import (
	"fmt"
	"github.com/garyburd/redigo/redis"
	"github.com/shirou/gopsutil/mem"
	"log"
	"strconv"
	"time"
)

type RedisConfig struct {
	Host     string
	Port     string
	Password string
}

/*
1.使用 redis benchmark 工具, 测试 10 20 50 100 200 1k 5k 字节 value 大小，redis get set 性能。
redis版本：5.0.14
以下是电脑中测试的结果
<1> redis-benchmark -t get,set -q -d 10
SET: 32541.49 requests per second
GET: 32102.73 requests per second

<2> redis-benchmark -t get,set -q -d 20
SET: 30656.04 requests per second
GET: 32851.51 requests per second

<3> redis-benchmark -t get,set -q -d 50
SET: 32216.49 requests per second
GET: 33670.04 requests per second

<4> redis-benchmark -t get,set -q -d 100
SET: 32478.08 requests per second
GET: 31969.31 requests per second

<5> redis-benchmark -t get,set -q -d 200
SET: 32404.41 requests per second
GET: 31240.24 requests per second

<6> redis-benchmark -t get,set -q -d 1000
SET: 31575.62 requests per second
GET: 31318.51 requests per second

<7> redis-benchmark -t get,set -q -d 5000
SET: 30816.64 requests per second
GET: 30057.11 requests per second
*/

/*
2.写入一定量的 kv 数据, 根据数据大小 1w-50w 自己评估, 结合写入前后的 info memory 信息 , 分析上述不同 value 大小下，平均每个 key 的占用内存空间。
*/
func main() {
	// redis相关配置
	var config RedisConfig
	config = RedisConfig{
		Host: "127.0.0.1",
		Port: "6379",
		Password: "",
	}
	selectDB := redis.DialDatabase(0) // 选择数据库
	setPassword := redis.DialPassword(config.Password) // 设置密码
	// 创建Redis连接
	client, err := redis.Dial("tcp", fmt.Sprintf("%s:%s", config.Host, config.Port), selectDB, setPassword)
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close() // 记得关闭连接
	// 生成一个起始1w字节的字符串
	str := "1"
	for i := 1; i < 10000; i++ {
		str += "0"
	}
	//循环向redis中插入数据
	for i := 0; i < 50; i++ {
		var value string
		startTime := time.Now().Unix()
		startMemory, err := mem.VirtualMemory()
		if err != nil {
			log.Fatal(err)
		}
		for n := 0; n <= i; n++ {
			value += str
		}
		// 向redis中放入数据：1w,2w,3w....50w(使用有效期的kv不用清理数据)
		if _, err := client.Do("Setex", "key_"+strconv.Itoa(i+1), 60,  value); err != nil {
			log.Fatal(err)
		}
		endTime := time.Now().Unix()
		endMemory, err := mem.VirtualMemory()
		if err != nil {
			log.Fatal(err)
		}
		// 排除内存消耗为负的情况
		var consume int64
		if int64(startMemory.Used) - int64(endMemory.Used) > 0 {
			consume = int64(startMemory.Used) - int64(endMemory.Used)
		}
		// 打印每次的结果
		fmt.Printf("Redis设置完成：%d，消耗时间：%ds\n", i, endTime-startTime)
		fmt.Printf("当前系统内存消耗：%d\n\n", consume)
	}
}
/*
...
随机截取部分数据插入后，内存变化记录，每一次执行都会有不同的变化
Redis设置完成：28，消耗时间：0s
当前系统内存消耗：0

Redis设置完成：29，消耗时间：0s
当前系统内存消耗：577536

Redis设置完成：30，消耗时间：0s
当前系统内存消耗：1028096

Redis设置完成：31，消耗时间：0s
当前系统内存消耗：880640

Redis设置完成：32，消耗时间：0s
当前系统内存消耗：1277952

Redis设置完成：33，消耗时间：0s
当前系统内存消耗：634880
...
*/
